package com.myassignment.util;


import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;

import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;
import org.xml.sax.Attributes;


public class XMLSAXUtility {
//    private Logger logger = Logger.getLogger(getClass());
    @SuppressWarnings("unchecked")
    public static List getInfos(String xml, XMLInfoMapper infoMapper) {
        XMLHandler handler = new XMLSAXUtility().new XMLHandler(infoMapper);
        try {
            XMLReader parser = XMLReaderFactory.createXMLReader();
            parser.setContentHandler(handler);
            parser.setErrorHandler(handler);
            if (!xml.startsWith("<?xml ")) {
                xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + xml;
            }
            StringReader sr = new StringReader(xml);
            parser.parse(new InputSource(sr));
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
        return handler.getInfos();
    }

    @SuppressWarnings("unchecked")
    public static List getReceivePacketInfos(String receivedData) {
        receivedData = "<Node>" + receivedData + "</Node>";
    return XMLSAXUtility.getInfos(receivedData, new XMLInfoMapper() {
        @Override
        public Object mapInfo(Attributes attributes) {
            DataPacketDto one = new DataPacketDto();
            for (int index = 0; index < attributes.getLength(); index++) {
                String attribute = attributes.getQName(index);
                if ("targetPort".equals(attribute)) {
                    one.setTargetPort(Integer.parseInt(attributes.getValue(attribute)));
                }
                if ("targetIpAdress".equals(attribute)) {
                    one.setTargetIpAdress(attributes.getValue(attribute));
                }
                if ("sourceAdress".equals(attribute)) {
                    one.setSourceAdress(attributes.getValue(attribute));
                }
                if ("timeStamp".equals(attribute)) {
                    one.setTimeStamp(attributes.getValue(attribute));
                }
                if ("dstUser".equals(attribute)) {
                    one.setDstUser(attributes.getValue(attribute));
                }
                if ("srcUser".equals(attribute)) {
                    one.setSrcUser(attributes.getValue(attribute));
                }
                if ("type".equals(attribute)) {
                    one.setType(Integer.parseInt(attributes.getValue(attribute)));
                }
                if ("TTL".equals(attribute)) {
                    one.setTTL(Integer.parseInt(attributes.getValue(attribute)));
                }
                if ("delay".equals(attribute)) {
                    one.setDelay(Integer.parseInt(attributes.getValue(attribute)));
                }
                if ("data".equals(attribute)) {
                    one.setData(attributes.getValue(attribute));
                }
            }
            return one;
        }

        @Override
        public boolean mapName(String localName) {
            return true;
        }});
    }
    class XMLHandler extends DefaultHandler {
        @SuppressWarnings("unchecked")
        private List infos = new ArrayList();
        private XMLInfoMapper mapper;
        public XMLHandler(XMLInfoMapper mapper) {
            super();
            this.mapper = mapper;
        }
        @SuppressWarnings("unchecked")
        public List getInfos() {
            return this.infos;
        }
        public void startDocument() {
        }

        public void endDocument() {
        }

        @SuppressWarnings("unchecked")
        public void startElement(String uri, String localName, String qName, Attributes attributes) {
            if (mapper.mapName(localName)) {
                infos.add(mapper.mapInfo(attributes));
            }
        }
        public void endElement(String uri, String name, String qName) {
        }

        public void characters(char []ch, int start, int length) {
            System.out.println("Characters:    \"");
            for (int i = start; i < start + length; i++) {
                switch (ch[i]) {
                case '\\':
                    System.out.println("\\\\");
                    break;
                case '"':
                    System.out.println("\\\"");
                    break;
                case '\n':
                    System.out.println("\\n");
                    break;
                case '\r':
                    System.out.println("\\r");
                    break;
                case '\t':
                    System.out.println("\\t");
                    break;
                default:
                    System.out.println(ch[i]);
                    break;
                }
            }
        }
    }
}
